package com.lzz.redis;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.Charset;

/**
 * 自定义一个序列化工具类，用fastjson。
 * 定义了经一个对象序列化和反序列的规则和过程
 * @author zhenzhen
 * @date 2018-12-19 下午7:39
 */
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    /**
     * 默认字符集
     */
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    /**
     * 将对象转化成JSON字符串，在序列化为二进制数据
     * @param t
     * @return
     * @throws SerializationException
     */
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        // 将对象转化成json字符串
        String jsonString = JSON.toJSONString(t, SerializerFeature.WriteClassName);
        // 将字符串转化成二进制数据
        byte[] serializationData = jsonString.getBytes(DEFAULT_CHARSET);
        return serializationData;
    }

    /**
     * 将序列化的的字节数据转化成字符串，再由fastJson转化成java对象
     * @param bytes
     * @return
     * @throws SerializationException
     */
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        // 开启AutoType功能，在1.2.25之后的版本，以及所有的.sec01后缀版本中，
        // autotype功能是受限的，和之前的版本不同，如果在升级的过程中遇到问题，
        // 可以通过以下方法配置。https://github.com/alibaba/fastjson/wiki/enable_autotype
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) JSON.parseObject(str, clazz);
    }
}
